/*
 * Handles the Google authentication. Make sure to bind the following callbacks:
 * 
 * loginSucceededBind(token) 
 * loginFailedBind(message)
 * loginFailedCaptchaBind(url, captchaToken, captchaUrl)
 */
var authn = {

	http : null,

	token : null,

	loginSucceededBind : null,

	loginFailedBind : null,

	loginFailedCaptchaBind : null,

	spreadsheetLogin : function(email, password) {
		this.login(email, password, "wise");
	},

	login : function(email, password, service) {
		this.http = new XMLHttpRequest();
		this.http.open('post', 'https://www.google.com/accounts/ClientLogin');
		this.http.onreadystatechange = this.processLoginResponse;
		this.http.setRequestHeader('content-type',
				'application/x-www-form-urlencoded');
		var token = 'accountType=HOSTED_OR_GOOGLE&Email=' + email + '&Passwd='
				+ password + '&service=' + service + '&source='
				+ Mojo.Controller.appInfo.id + '-'
				+ Mojo.Controller.appInfo.version;
		this.http.send(token);
	},

	processLoginResponse : function() {
		if (authn.http.readyState == 4) {
			if (authn.http.status == 200) {
				authn.handle200Response(authn.http.responseText);
			} else {
				if (authn.http.status == 403) {
					var captchaRequired = false;
					var url = null;
					var captchaToken = null;
					var captchaUrl = null;
					var tokens = authn.http.responseText.split('\n');
					for (i = 0; i < tokens.length; ++i) {
						var token = tokens[i].split('=');
						if (token[0] == 'Error') {
							if (token[1] == 'BadAuthentication') {
								authn
										.loginFailedBind("The username or password you entered is incorrect.");
							} else if (token[1] == 'NotVerified') {
								authn
										.loginFailedBind("The account email address has not been verified. "
												+ "You need to access their Google account directly "
												+ "to resolve the issue before logging in.");
							} else if (token[1] == 'TermsNotAgreed') {
								authn
										.loginFailedBind("You have not agreed to terms. "
												+ "You need to access their Google account directly to resolve the issue before logging in.");
							} else if (token[1] == 'CaptchaRequired') {
								captchaRequired = true;
							} else if (token[1] == 'Unknown') {
								authn.loginFailedBind("Unknown error.");
							} else if (token[1] == 'AccountDeleted') {
								authn.loginFailedBind("Account deleted.");
							} else if (token[1] == 'AccountDisabled') {
								authn.loginFailedBind("Account disabled.");
							} else if (token[1] == 'ServiceDisabled') {
								authn.loginFailedBind("Service disabled.");
							} else if (token[1] == 'ServiceUnavailable') {
								authn
										.loginFailedBind("The service is not available; try again later.");
							} else {
								// should not happen
								Mojo.Log.error(authn.http.status);
								Mojo.Log.error(authn.http.responseText);
							}
						} else if (token[0] == 'Url') {
							url = token[1];
						} else if (token[0] == 'CaptchaToken') {
							captchaToken = token[1];
						} else if (token[0] == 'CaptchaUrl') {
							captchaUrl = token[1];
						}
						if (captchaRequired) {
							authn.loginFailedCaptchaBind(url, captchaToken,
									captchaUrl);
						}
					}
				} else {
					// should not happen
					Mojo.Log.error(authn.http.status);
					Mojo.Log.error(authn.http.responseText);
				}
			}
		}
	},

	handle200Response : function(responseText) {
		var tokens = responseText.split('\n');
		for (i = 0; i < tokens.length; ++i) {
			var token = tokens[i].split('=');
			if (token[0] == 'Auth') {
				authn.token = token[1];
				authn.loginSucceededBind(authn.token);
				return;
			}
		}
	}
};